package com.situ.gcbs.server.common;

import com.situ.gcbs.server.util.Exceptions;
import com.situ.gcbs.server.util.Requests;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 功能：统一异常处理
 *
 * @author 千堆雪
 * @version 1.0.0
 * @since 2024/5/16
 * <p>
 * created by 千堆雪 on 2024/5/16 11:10, last modified by 千堆雪 on 2024/5/16 11:10
 */
@Component
public class ApiExceptionResolver implements HandlerExceptionResolver, Ordered {
    private static final Log LOGGER = LogFactory.getLog(ApiExceptionResolver.class);

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView mav = new ModelAndView();

        String errorMsg = "服务器异常";
        Object error = request.getAttribute("error");
        if (error != null) {
            errorMsg = error.toString();//错误信息
        }

        //记录日志
        LOGGER.error(errorMsg, ex);
        mav.addObject("error", errorMsg);
        mav.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);//500服务器异常
        mav.addObject("code", HttpStatus.INTERNAL_SERVER_ERROR.value());
        mav.addObject("exception", ex);

        if (Requests.isAjaxRequest(request)) {//如果是ajax请求
            MappingJackson2JsonView view = new MappingJackson2JsonView();
            mav.setView(view);

            Map<String, Object> map = new HashMap<>();
            map.put("time", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
            map.put("trace", Exceptions.toString(ex));
            mav.addObject("exception", map);//覆盖上面存储ex对象
            return mav;
        }

        return null;//返回null，继续交由其它HandlerExceptionResolver处理
    }
}
